package upload

import (
	"context"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/util/guid"
	"path/filepath"
	"server/internal/consts"
	"server/internal/model"
	"server/internal/service"
)

// 1.开通阿里云oss：https://www.aliyun.com/product/oss
// 2.创建bucket空间
// 3.新增API的秘钥后在配置文件进行配置 fileUpload.aliYunOss ：https://ram.console.aliyun.com/profile/access-keys

type AliYunOssUpload struct {
}

func (L *AliYunOssUpload) UploadFile(ctx context.Context, file *ghttp.UploadFile, fileSubject string) (out model.FileUploadOutput, err error) {
	bucket, err := L.newBucket(ctx)
	if err != nil {
		return
	}
	// 生成一个文件路径作为文件对象的KEY
	filename := guid.S() + filepath.Ext(file.Filename)
	objectKey := GenerateUploadFilePath(ctx, filename, consts.FileUploadStorageTypeAliYunOss, fileSubject)
	// 判断文件是否存在
	exist, err := bucket.IsObjectExist(objectKey)
	if err != nil {
		return
	}
	if exist {
		err = gerror.New("文件名已存在，上传失败")
		return
	}
	// 上传文件
	if fileReader, err := file.Open(); err != nil {
		return out, err
	} else if err = bucket.PutObject(objectKey, fileReader); err != nil {
		return out, err
	}
	// 处理文件上传后的相关路径
	out.AbsolutePath = objectKey
	out.RelativePath = objectKey
	out.URL = FormatUploadFileURL(ctx, objectKey, consts.FileUploadStorageTypeAliYunOss)
	return
}

func (L *AliYunOssUpload) DeleteFile(ctx context.Context, key string) (err error) {
	bucket, err := L.newBucket(ctx)
	if err != nil {
		return
	}
	// 判断文件是否存在
	exist, err := bucket.IsObjectExist(key)
	if err != nil {
		return
	}
	if !exist {
		err = gerror.New("文件不存在，删除失败")
		return
	}
	// 删除文件
	err = bucket.DeleteObject(key)
	if err != nil {
		return
	}
	return nil
}

func (L *AliYunOssUpload) newBucket(ctx context.Context) (bucket *oss.Bucket, err error) {
	config, err := service.File().GetFileUploadConfig(ctx)
	if err != nil {
		return
	}
	client, err := oss.New(config.AliYunOSS.Endpoint, config.AliYunOSS.AccessKeyId, config.AliYunOSS.AccessKeySecret)
	if err != nil {
		return
	}

	bucket, err = client.Bucket(config.AliYunOSS.BucketName)
	if err != nil {
		return
	}
	return
}
